package es.uji.icc.robot.grasp;

import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.MultivaluedMap;
import javax.ws.rs.core.Response;

import com.sun.jersey.api.client.Client;
import com.sun.jersey.api.client.ClientResponse;
import com.sun.jersey.api.client.UniformInterfaceException;
import com.sun.jersey.api.client.WebResource;
import com.sun.jersey.core.util.MultivaluedMapImpl;

/**
 * Makes possible to control a robot. This client uses REST protocol to
 * communicate to a robot server
 * 
 * Changelog
 * 01/03/2012 Roger. It seems that when this class is called from MatLab, there is some bug (http://stackoverflow.com/questions/4076564/calling-a-jax-ws-webservice-from-inside-matlab) and changes the http headers. That makes an error in the JaxB parser (A message body reader for Java class  and Java type class , and MIME media type application/octet-stream was not found) because the header about the content type is not what JAXB expected  
 * 
 * @author Roger Esteller
 * @version 1
 * 
 */
public class Grasp {

	Client client = new Client();	
	protected String serverAddress;
	WebResource webResource;

	public Grasp() {
		
	}
	
	public Grasp(String serverURI, int timeout) {

//		this.serverURI = serverURI;
		this.serverAddress =  serverURI;

		client = Client.create();
		client.setConnectTimeout(timeout);

		webResource = client.resource(serverAddress);
	}
	
	public String showVersion() {
		return "Grasp REST Client v.1.0.0";		
	}
	
	
	
	public String Ping() throws GraspException {

	    WebResource service = null;
		ClientResponse response = null;
		String responseXML = null;
		GraspResponse graspResponse = null;
		try {			
			service = client.resource(serverAddress);			
			response = service.path("ping").accept(MediaType.APPLICATION_XML)
					.get(ClientResponse.class);			
			if (Response.Status.OK.getStatusCode() == response.getStatus()) {
				
				// See changelog 01/03/2012
				// robotResponse = response.getEntity(RobotResponse.class);
                // I should do it manually
				responseXML =  response.getEntity(String.class);
				graspResponse = new GraspResponse(responseXML);
				return graspResponse.getMessage();
			
			} else {				
				throw new GraspException("Unexpected response from the server, status: "
						+ response.getStatus());
			}
		} catch (com.sun.jersey.api.client.ClientHandlerException e) {
						
			throw new GraspException(e.getMessage());
								
		} catch (UniformInterfaceException e) {
			
			  			 
			throw new GraspException(e.getMessage(), e.getResponse().getStatus());
			
		}
	
	}

	

	public void Open() throws GraspException {
		WebResource service = null;
		ClientResponse response = null;
		MultivaluedMap<String, String> postParams = new MultivaluedMapImpl();
		postParams.add("operation", "open" );			
		
		try {
			service = client.resource(serverAddress);
			response = service.path("grasp")
					.post(ClientResponse.class, postParams);
		    if (Response.Status.OK.getStatusCode() != response.getStatus()) {
				throw new GraspException("Unexpected response from the server, status: "
						+ response.getStatus() + ". " + response.getEntity(String.class));
			}
		} catch (com.sun.jersey.api.client.ClientHandlerException e) {
			throw new GraspException(e.getMessage());
		} catch (UniformInterfaceException e) {
			throw new GraspException(e.getMessage(), e.getResponse().getStatus());
		}
	}
	

	public void Close() throws GraspException {
		WebResource service = null;
		ClientResponse response = null;
		MultivaluedMap<String, String> postParams = new MultivaluedMapImpl();
		postParams.add("operation", "close" );			
		
		try {
			service = client.resource(serverAddress);
			response = service.path("grasp")
					.post(ClientResponse.class, postParams);
		    if (Response.Status.OK.getStatusCode() != response.getStatus()) {
				throw new GraspException("Unexpected response from the server, status: "
						+ response.getStatus() + ". " + response.getEntity(String.class));
			}
		} catch (com.sun.jersey.api.client.ClientHandlerException e) {
			throw new GraspException(e.getMessage());
		} catch (UniformInterfaceException e) {
			throw new GraspException(e.getMessage(), e.getResponse().getStatus());
		}
	}


}
